﻿#include "uisigtableview.h"
#include "shlib/viewmodel/imodel.h"
#include "shlib/viewmodel/uitoast.h"
#include <QMenu>
#include <QMouseEvent>
#include <QJsonArray>
#include <QJsonDocument>
#include <QApplication>
#include <QClipboard>
#include <QJsonObject>

#include <ElaMenu.h>


UiSigTableView::UiSigTableView( QWidget *parent):ElaTableView(parent)
{
    this->setWindowFlags(Qt::FramelessWindowHint);
    this->setStyleSheet("background-color: rgba(0, 0, 0, 0);");

    m_menu = new ElaMenu(this);

    m_copyAction = m_menu->addAction("复制");
    // 连接“复制”动作的信号和槽
    connect(m_copyAction,&QAction::triggered,this,&UiSigTableView::slotMenuCopySig);
    m_pasteAction = m_menu->addAction("粘贴");
    // 连接“粘贴”动作的信号和槽
    connect(m_pasteAction,&QAction::triggered,this,&UiSigTableView::slotMenuPasteSig);
    m_batchAutoIncrementAction = m_menu->addAction("批量自增");
    // 连接“批量自增”动作的信号和槽
    connect(m_batchAutoIncrementAction,&QAction::triggered,this,&UiSigTableView::slotMenuBatchAutoIncrement);
    m_batchReplaceColAction = m_menu->addAction("批量替换列内容");
    // 连接“批量替换列内容”动作的信号和槽
    connect(m_batchReplaceColAction,&QAction::triggered,this,&UiSigTableView::slotMenuBatchReplaceCol);
    m_batchIncrementColAction = m_menu->addAction("批量自增列内容");
    // 连接“批量自增列内容”动作的信号和槽
    connect(m_batchIncrementColAction,&QAction::triggered,this,&UiSigTableView::slotMenuBatchIncrementCol);

    m_deleteAction = m_menu->addAction("删除");
    // 连接“删除”动作的信号和槽
    connect(m_deleteAction,&QAction::triggered,this,&UiSigTableView::slotMenuDeleteSig);
}

/**
 * @brief 处理表格视图的鼠标按下事件。
 *
 * 该函数首先调用父类的鼠标按压事件处理函数，然后检查是否是右键按下。如果是右键按下，它会判断点击位置是否在有效单元格上，
 * 如果是空位置则清除当前选择，然后根据是否有选择项来启用或禁用复制和删除动作，并将右键菜单显示在鼠标点击的全局位置。
 *
 * @param event 指向鼠标事件的指针，包含了事件的详细信息。
 */
void UiSigTableView::mousePressEvent(QMouseEvent *event)
{
    // 调用父类的鼠标按压事件处理函数
    QTableView::mousePressEvent(event);

    // 检查是否是右键按下
    if(event->buttons() == Qt::RightButton)
    {
        // 检查是否点击在无效区域（即非表格内容区域）
        bool bPressEmpty = !this->indexAt(event->pos()).isValid();
        if(bPressEmpty)
            this->clearSelection(); // 如果点击在无效区域，则清除当前选择

        // 判断是否有选中项，并据此启用或禁用复制和删除菜单项
        bool bSelect = this->selectedIndexes().size()>0;
        m_copyAction->setEnabled(bSelect);
        m_deleteAction->setEnabled(bSelect);
        m_batchReplaceColAction->setEnabled(bSelect);
        m_batchIncrementColAction->setEnabled(bSelect);

        m_batchAutoIncrementAction->setEnabled(this->isSelectSingleRow());


        // 设置右键菜单的位置并显示
        m_menu->move(event->globalPos());
        m_menu->show();
    }
}

/**
 * @brief 执行菜单项删除信号的操作
 *
 * 该函数被调用时，将删除选中的信号。首先获取当前选中的索引列表，然后遍历这些索引，
 * 如果索引所在的列是第一列，则从该索引中提取出信号数据，并将其添加到待删除的信号数据列表中。
 * 最后，发出删除信号，通知其他部件删除这些信号。
 */
void UiSigTableView::slotMenuDeleteSig()
{
    // 获取当前选中的所有索引
    auto indexs = this->selectedIndexes();
    QList<QSharedPointer<IModel>> dataList;
    // 遍历所有选中的索引，收集需要删除的信号数据
    for(auto index:indexs)
    {
        // 仅当索引位于第一列时，才处理该索引
        if(0 == index.column())
        {
            // 从索引中获取信号数据，并添加到待删除的数据列表中
            auto data = index.data(Qt::UserRole).value<QSharedPointer<IModel>>();
            dataList<<data;
        }
    }
    // 发出删除信号，传入待删除的信号数据列表
    emit sigDeleteSig(dataList);
}

void UiSigTableView::slotMenuCopySig()
{
    // 获取当前选中的所有索引
    auto indexs = this->selectedIndexes();

    // 创建一个QJsonArray来存储所有选中项的JSON表示
    QJsonArray jsonArray;

    // 遍历所有选中的索引，收集信号数据并转换为JSON
    for (auto index : indexs) {
        if (0 == index.column()) {
            // 从索引中获取信号数据
            QSharedPointer<IModel> tempdata = index.data(Qt::UserRole).value<QSharedPointer<IModel>>();
            if (tempdata) {
                // 将信号数据转换为JSON对象并添加到数组中
                QJsonObject jsonObject = tempdata->toJson();
                jsonArray.append(jsonObject);
            }
        }
    }

    // 如果有数据，将其转换为JSON字符串并复制到剪贴板
    if (!jsonArray.isEmpty()) {
        QJsonDocument jsonDoc(jsonArray);
        QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
        QApplication::clipboard()->setText(jsonString);

        //发送复制信号
        emit sigCopySig();
    }
}

void UiSigTableView::slotMenuPasteSig()
{
    emit sigPasteSig();
}
/**
 * @brief 批量替换列的操作。
 * 当前方法被调用时，会检查是否有选中的行，然后打开一个对话框以获取要替换的列和替换值，
 * 最后发出信号以执行批量替换操作。
 */
void UiSigTableView::slotMenuBatchReplaceCol()
{

}

/**
 * @brief 批量自增列的操作。
 * 被调用时，会检查是否有选中的行，然后打开一个对话框以获取自增的字段、值和起始索引，
 * 最后发出信号以执行批量自增操作。
 */
void UiSigTableView::slotMenuBatchIncrementCol()
{

}

/**
 * @brief 执行行的批量自增操作。
 * 仅当选中的行数为1时执行，会根据选中的行的数据，创建新的信号数据并添加到数据库，
 * 同时发出信号以更新用户界面。
 */
void UiSigTableView::slotMenuBatchAutoIncrement()
{

}

/**
 * @brief 检查是否只选中了一行。
 * 
 * @return true 当且仅当只选中了一行时返回true。
 */
bool UiSigTableView::isSelectSingleRow()
{
    auto indexList = this->selectedIndexes();
    int row = -1;
    if(indexList.size()<=0)
        return false;
    // 遍历所有选中行以检查是否只选中了一行
    for(auto index:indexList)
    {
        if(-1 == row)
            row = index.row();

        if(index.row() != row)
            return false;
    }
    return true;
}
